package Demo;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: DELL
 * Date: 2023-01-10
 * Time: 21:11
 */

// 该类定义定时器中得任务
/*class MyTask implements Comparable<MyTask> {
    // 要执行得任务内容
    private Runnable runnable;

    // 任务执行时间(毫秒级表示)
    private long time;

    // 任务构造器
    public MyTask(Runnable runnable, long time) {
        // 返回当前执行得任务和时间
        this.runnable = runnable;
        this.time = time;
    }

    // 获取当前任务时间
    public long getTime() {
        return time;
    }

    // 执行任务
    public void run() {
        runnable.run(); // 调用runnable.run方法
    }

    @Override
    public int compareTo(MyTask o) {
        // this 比 o 小, 返回 < 0 得值
        // this 比 o 大, 返回 > 0 得值
        // this 和 o 相同, 返回 0
        // 当前需要得要求为, 队首元素是时间最小得任务
        return (int) (this.time - o.time);
    }

}


//定时器
class MyTimer {
    //扫描线程
    private Thread t = null;

    // 有一个阻塞优先级队列,来保存任务
    private PriorityBlockingQueue<MyTask> queue = new PriorityBlockingQueue<MyTask>();

    // 专门使用这个对象来进行加锁/等待通知
    private Object lock = new Object();

    // 构造方法
    public MyTimer() {
        // 扫面线程得工作
        t = new Thread() {
            @Override
            public void run() {
                while (true) {
                    try {
                        // 取出对手元素,检查看队首元素任务是否到达执行时间
                        // 时间未倒, 将任务阻塞回队列之中
                        // 时间到了, 取出任务进行执行

                        System.out.println("this 2 " + this); // 观察是谁再进行调用(锁对象)
                        synchronized (this) {
                            MyTask myTask = queue.take(); // 取出队首任务
                            long curTime = System.currentTimeMillis();  // 返回当前时间(单位毫秒级)
                            if (curTime < myTask.getTime()) {
                                // 取出得当前任务还未到达执行时间 无需执行
                                // 放回队列中继续阻塞等待
                                queue.put(myTask);

                                // 任务时间减去当前时间 就是阻塞等待时间
                                this.wait(myTask.getTime() - curTime); // 阻塞等待到第一个任务时间得到来
                            } else {
                                // 到达执行时间了, 调用run方法执行任务
                                myTask.run();
                            }
                        }
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        t.start();
    }

    // 在指定时间安排指定任务
    public void schedule(Runnable runnable, long after) {
        // 参数1 指定任务
        // 参数2 指定时间(在多少毫秒之后执行) -- 注意时间换算
        // 此处参数after为多少秒后需要执行得任务时间
        MyTask myTask = new MyTask(runnable, System.currentTimeMillis() + after);
        // 指定时间到达后, 将这个任务塞进队列中
        queue.put(myTask);
        System.out.println("this 1 " + this); // 观察是谁再执行schedule
        synchronized (this) {
            this.notify();
        }
    }
}*/

public class Thread_Demo21 {

    /*public static void main(String[] args) {
        MyTimer myTimer = new MyTimer(); // 创建定时器实例
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行任务1");
            }
        }, 3000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行任务2");
            }
        }, 2000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行任务3");
            }
        }, 1000);
    }*/
}
